package com.itita.ww2.model.army;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang.StringUtils;

import com.itita.ww2.core.WW2Exception;
import com.itita.ww2.data.ArmyConfig;
import com.itita.ww2.enums.WW2ExceptionCode;
import com.itita.ww2.game.user.UserInventoryManager;
import com.itita.ww2.model.item.ItemEquip;
import com.itita.ww2.model.item.ds.ItemValue;
import com.itita.ww2.model.item.enums.ItemPrimaryType;
import com.itita.ww2.model.user.UserProfile;
import com.smartfoxserver.v2.entities.data.ISFSObject;
import com.smartfoxserver.v2.entities.data.SFSObject;

/**
 * 玩家的兵兵
 */
public class UserArmy {
	//
	protected transient UserProfile userProfile;
	//
	protected String code; // 代号
	protected int level; // 等级
	protected int exp; // 当前经验
	protected boolean unlocked; // 是否已解锁
	protected int count; // 数量
	protected int produceCount; // 当前正在生产的数量

	public int getProduceCount() {
		return produceCount;
	}

	// 装备
	protected Map<String, String> equipMap;
	//
	protected transient ArmyType type;

	public UserArmy(UserProfile userProfile, String code, int level, int exp, int count, boolean unlocked) {
		this.userProfile = userProfile;
		this.code = code;
		this.type = ArmyType.idValueOf(this.code);
		this.level = level;
		this.exp = exp;
		this.count = count;
		this.produceCount = 0;
		this.unlocked = unlocked;
		// 
		equipMap = new HashMap<>();
		// 格子填空
		for (int i = 0; i < 6; ++i) {
			equipMap.put("G00" + (i + 1), "");
		}
	}

	public static enum ArmyType {
		SOLDIER("U0"), // 小杂兵 U0XX
		ARMOREDVEHICLE("U1"), // 装甲车 U1XX
		TANK("U2"), // 坦克 U2XX
		;
		private String code;

		public String getValue() {
			return this.code;
		}

		private ArmyType(String code) {
			this.code = code;
		}

		public static ArmyType idValueOf(String id) {
			for (ArmyType ret : values()) {
				if (id.startsWith(ret.getValue())) {
					return ret;
				}
			}
			return null;
		}
	}

	/**
	 * 获取装备列表
	 */
	public Map<String, String> getEquipmentList() {
		return this.equipMap;
	}

	/**
	 * 获取格子内装备ID
	 */
	public String getEquipmentByGrid(String grid) {
		return this.equipMap.get(grid);
	}

	public void checkGrids() {
		for (int i = 0; i < 5; ++i) {
			String grid = "G00" + (i + 1);
			String originUUID = equipMap.get(grid);
			if (StringUtils.isNotBlank(originUUID)) {
				if (userProfile.getInventory().getItemByUUID(originUUID) == null) {
					equipMap.put(grid, "");
				}
			}
		}
	}

	/**
	 * 更换装备
	 * @param grid 格子序号
	 * @param uuid 新装备的uuid
	 * @return 是否可以更换(已经更换成功)
	 */
	public void equip(String grid, String uuid) throws WW2Exception {
		UserInventoryManager inventory = userProfile.getInventory();
		ItemValue new_iv = inventory.getItemByUUID(uuid);
		if (new_iv == null) {
			throw new WW2Exception();
		}
		// 要装上的物品是否是装备,是否正在被其他兵儿装备着
		if (new_iv.getItem().getPrimaryType() != ItemPrimaryType.EQUIPMENT) {
			throw new WW2Exception();
		}
		ItemEquip newEquip = (ItemEquip) new_iv.getItem();
		if (newEquip.isUsed()) {
			throw new WW2Exception();
		}
		if (newEquip.getLv() > this.level) {
			throw new WW2Exception(WW2ExceptionCode.LEVEL_LIMIT);
		}

		// 检查格子内是否已经有装备辣,有的话就拆卸
		String originUUID = equipMap.get(grid);
		if (StringUtils.isNotBlank(originUUID)) {
			ItemValue originItem = inventory.getItemByUUID(originUUID);
			if (originItem != null) {
				ItemEquip originEquip = (ItemEquip) originItem.getItem();
				//				// 有装备且itemId相同,不换
				//				if (originEquip.getItemId().equals(newEquip.getItemId())) {
				//					throw new WW2Exception(WW2ExceptionCode.DUPLICATE_OPT);
				//				}
				// 有装备,拆卸
				originEquip.setUsed(false);
				equipMap.put(grid, "");
				inventory.mergeItem(originItem);
				//				if (mergedIV == null) {
				//					originEquip.setUsed(false);
				//				} else {
				//					equipMap.put(grid, "");
				//				}
			}
			//			else {
			//				throw new WW2Exception();
			//			}
		}
		ItemValue partedIV = inventory.partItem(new_iv);
		newEquip = (ItemEquip) partedIV.getItem();

		// 装上去
		newEquip.setUsed(true);

		equipMap.put(grid, newEquip.getUuid());
	}

	/**
	 * 兵兵涨经验(并升级)
	 * @return 是否增长经验
	 */
	public boolean growExp(int exp) {
		// 兵满级时不能增长经验
		if (this.level >= ArmyConfig.getArmyMaxLv(code)) {
			return false;
		}
		this.exp += exp;
		// 判断是否升级
		int needExp = ArmyConfig.getArmyUpExp(code, level);
		if (needExp <= this.exp) {
			// 兵种等级不能大于对应兵营等级(前提解锁)
			if (userProfile.getBDManager().isBuildingUnlocked(this.type)) {
				if (this.level >= userProfile.getBDManager().getBuildingByArmyType(type).getLevel()) {
					this.exp = needExp - 1;
					return true;
				}
				upgrade();
			} else {
				this.exp = needExp - 1;
				return true;
			}
		}
		return true;
	}

	/**
	 * 升级兵
	 */
	private void upgrade() {
		if (!unlocked) {
			return;
		}
		this.level++;
		// 保留多余经验
		this.exp -= ArmyConfig.getArmyUpExp(code, level - 1);
	}

	/**
	 * 操作数量
	 */
	public void countOper(int value) {
		int newCount = this.count + value;
		if (newCount < 0) {
			newCount = 0;
		}
		this.count = newCount;
	}

	/**
	 * 生产
	 */
	public void produce(int value) {
		this.produceCount = value;
	}

	/**
	 * 生产完成
	 */
	public void produceComplete() {
		this.count += this.produceCount;
		this.produceCount = 0;
	}

	public String getCode() {
		return code;
	}

	public int getLevel() {
		return level;
	}

	public boolean isUnlocked() {
		return unlocked;
	}

	public int getCount() {
		return count;
	}

	public void setUnlocked(boolean unlocked) {
		this.unlocked = unlocked;
	}

	public static UserArmy newFromJsonData(UserProfile userProfile, ISFSObject data) {
		UserArmy ret = new UserArmy(userProfile, data.getUtfString("code"), data.getInt("lv"), data.getInt("exp"),
				data.getInt("count"), data.getBool("unlocked"));
		ret.produceCount = data.getInt("pc"); // 生产数量
		ret.unlocked = data.getBool("unlocked");
		ISFSObject equipObj = data.getSFSObject("equip");
		for (String key : equipObj.getKeys()) {
			ret.equipMap.put(key, equipObj.getUtfString(key));
		}
		return ret;
	}

	/**
	 * 判定一下code是不是army
	 */
	public static boolean isArmy(String code) {
		return code.startsWith("U");
	}

	public ISFSObject toSFSObject() {
		ISFSObject ret = SFSObject.newInstance();
		ret.putUtfString("code", code);
		ret.putBool("unlocked", unlocked);
		ret.putInt("lv", level);
		ret.putInt("exp", exp);
		ret.putInt("count", count);
		ret.putInt("pc", produceCount);
		// 
		ISFSObject equipObj = SFSObject.newInstance();
		for (Entry<String, String> entry : equipMap.entrySet()) {
			equipObj.putUtfString(entry.getKey(), entry.getValue());
		}
		ret.putSFSObject("equip", equipObj);
		return ret;
	}
}
